package spring.aop.test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy;

public class ProxyServiceA_ extends Proxy implements IServiceA {

    private static final long serialVersionUID = 1L;

    protected ProxyServiceA_(InvocationHandler h) {
        super(h);
    }

    @Override
    public void say(int s) {
        StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
        StackTraceElement m1Stack = stackTrace[1];
        String currentMethodName = m1Stack.getMethodName();
        System.out.println(currentMethodName);
        System.out.println(s);
        try {
//            Object result = h.invoke(this, IServiceA.class.getMethod(currentMethodName, int.class), new Object[] {s});
            Object obj = getFieldValueByClass(h, IServiceA.class);
            System.out.println(obj);
            Object result = h.invoke(obj, IServiceA.class.getMethod(currentMethodName, int.class), new Object[] {s});
//            System.out.println(result);
        } catch (Throwable e) {
            e.printStackTrace();
        }
    }

    public Object getFieldValueByClass(Object obj, Class<?> fieldCls) {
        System.out.println(h.getClass());
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field field : fields) {
            System.out.println(field.getName());
            field.setAccessible(true);
            if(field.getType() != Object.class) continue;
            Object object = null;
            try {
                object = field.get(obj);
            } catch (IllegalArgumentException | IllegalAccessException e1) {
                e1.printStackTrace();
            }
            if(object != null && fieldCls.isAssignableFrom(object.getClass())) {
                return object;
            }
        }
        return null;
    }
    
    public static Object getProxyInstance(InvocationHandler h) {
        return new ProxyServiceA_(h);
    }

    public static void main(String[] args) {
        ServiceA sa = new ServiceA("TLX");
        IServiceA serviceA = (IServiceA) ProxyServiceA_.getProxyInstance(new MyIh(sa));
        serviceA.say(100);
    }

}
